/*
 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include "iot_gpio_ex.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_uart.h"
#include "hi_uart.h"
#include "iot_watchdog.h"
#include "iot_errno.h"

#define UART_BUFF_SIZE 2048
#define U_SLEEP_TIME   100000


#define MAX_BUFFER_SIZE 1024
#define MAX_GPRMC_LENGTH 100 // 假设$GPRMC数据帧的最大长度

#include <math.h> // 用于使用 atof 函数

// 定义结构体存储解析结果
typedef struct {
    char utc_time[9]; // 格式为HHMMSS.SS
    double latitude; // 纬度
    char latitude_dir; // 'N' 或 'S'
    double longitude; // 经度
    char longitude_dir; // 'E' 或 'W'
    hi_bool valid;
} GPSParsedData;

GPSParsedData parseGPRMC(char* gprmcFrame) {
    GPSParsedData data;
    int scanResult;

	char temptime[9];
    // 明确检查sscanf返回值以辅助调试
    scanResult = sscanf(gprmcFrame + 7, 
                        "%8[^,],%*[^,],%lf,%c,%lf,%c,%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*c",
                        temptime, &data.latitude, &data.latitude_dir, 
                        &data.longitude, &data.longitude_dir);
    if (scanResult != 5) {
        data.valid = HI_FALSE;
        printf("Error parsing GPRMC frame. sscanf returned %d\n", scanResult);
        memset(&data, 0, sizeof(GPSParsedData));
        return data;
    }

    // 确保时间字符串正确结束
    temptime[8] = '\0';

	data.utc_time[0]=temptime[0];
	data.utc_time[1]=temptime[1];
	data.utc_time[2]=':';
	data.utc_time[3]=temptime[2];
	data.utc_time[4]=temptime[3];
	data.utc_time[5]=':';
	data.utc_time[6]=temptime[4];
	data.utc_time[7]=temptime[5];
	data.utc_time[8]='\0';
    // 转换纬度和经度为十进制度数
    data.latitude /= 100.0;
    data.longitude /= 100.0;

    return data;
}


char* extractFirstGPRMC(char* buffer, size_t bufferLen) {
    char* gprmcStart = strstr(buffer, "$GNRMC,");
    if (gprmcStart != NULL) {
        // 查找换行符，以确定$GPRMC数据帧的结束位置
        char* gprmcEnd = strstr(gprmcStart, "\r\n");
        if (gprmcEnd != NULL) {
            // 计算数据帧的长度，并确保不超过预定最大长度
            size_t gprmcLength = gprmcEnd - gprmcStart + 2; // 包括'\r\n'
            if (gprmcLength <= MAX_GPRMC_LENGTH) {
                // 复制数据帧到一个新的字符串
                char* gprmcFrame = malloc(gprmcLength + 1); // +1是为了结尾的空字符
                strncpy(gprmcFrame, gprmcStart, gprmcLength);
                gprmcFrame[gprmcLength] = '\0'; // 确保字符串正确结束
                return gprmcFrame;
            } else {
                printf("Detected GPRMC frame exceeds the maximum allowed length.\n");
            }
        } else {
            printf("Could not find end of GPRMC frame in buffer.\n");
        }
    } else {
        printf("No GPRMC frame found in buffer.\n");
    }
    return NULL;
}


void Uart1GpioInit(void)
{
    IoTGpioInit(IOT_IO_NAME_GPIO_0);
    // 设置GPIO0的管脚复用关系为UART1_TX Set the pin reuse relationship of GPIO0 to UART1_ TX
    IoSetFunc(IOT_IO_NAME_GPIO_0, IOT_IO_FUNC_GPIO_0_UART1_TXD);
    IoTGpioInit(IOT_IO_NAME_GPIO_1);
    // 设置GPIO1的管脚复用关系为UART1_RX Set the pin reuse relationship of GPIO1 to UART1_ RX
    IoSetFunc(IOT_IO_NAME_GPIO_1, IOT_IO_FUNC_GPIO_1_UART1_RXD);
}

void Uart1Config(void)
{
    uint32_t ret;
    /* 初始化UART配置，波特率 9600，数据bit为8,停止位1，奇偶校验为NONE */
    /* Initialize UART configuration, baud rate is 9600, data bit is 8, stop bit is 1, parity is NONE */
    IotUartAttribute uart_attr = {
        .baudRate = 9600,
        .dataBits = 8,
        .stopBits = 1,
        .parity = 0,
        .rxBlock = IOT_UART_BLOCK_STATE_BLOCK,
    };
    ret = IoTUartInit(HI_UART_IDX_1, &uart_attr);
    if (ret != IOT_SUCCESS) {
        printf("Init Uart1 Falied Error No : %d\n", ret);
        return;
    }
}


static void UartTask(void)
{

    uint32_t count = 0;
    uint32_t len = 0;
    unsigned char uartReadBuff[UART_BUFF_SIZE] = {0};

    // 对UART1的一些初始化 Some initialization of UART1
    Uart1GpioInit();
    // 对UART1参数的一些配置 Some configurations of UART1 parameters
    Uart1Config();
    


    while (1) {

        
        len = IoTUartRead(HI_UART_IDX_1, uartReadBuff, UART_BUFF_SIZE);


        if (len > 0) {
            IoTUartWrite(HI_UART_IDX_1, uartReadBuff, 64);
            printf("Uart Read Data [ %d ] is: \r\n %s ", count, uartReadBuff);
            printf("len:%d\n",len);
        }

            //char buffer[MAX_BUFFER_SIZE] = "deawed$GNRMC,123519,A,4807.432,N,01131.321,E,022.4,084.4,230394,003.1,W*6A\r\nsda sOther data here...\r\n";
            //char* gprmcData = extractFirstGPRMC(uartReadBuff, sizeof(uartReadBuff));
            //char* gprmcData = extractFirstGPRMC(buffer, sizeof(buffer));
        
        usleep(U_SLEEP_TIME);
        count++;
    }
}

void UartExampleEntry(void)
{
    osThreadAttr_t attr;
    IoTWatchDogDisable();

    attr.name = "UartTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 5 * 1024; // 任务栈大小*1024 stack size 5*1024
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)UartTask, NULL, &attr) == NULL) {
        printf("[UartTask] Failed to create UartTask!\n");
    }
}

APP_FEATURE_INIT(UartExampleEntry);
